import os
import time

from django.conf import settings
from django.http import StreamingHttpResponse
from rest_framework.exceptions import APIException

from file_manage.models import FileManage


class FileManageService:
    @staticmethod
    def get_file_data(full_path):
        if not os.path.isfile(full_path):
            raise APIException('文件不存在')
        # 打开文件
        with open(full_path, 'rb') as f:
            # 分块读取文件
            for chunk in f:
                yield chunk

    @classmethod
    def download_file(cls, instance):
        file_name = instance.file_name
        file_path = instance.file_path
        response = StreamingHttpResponse(cls.get_file_data(file_path))
        # 设置响应头
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="{}"'.format(
            file_name.encode('utf-8').decode('ISO-8859-1'))
        # 为了使前端获取到Disposition，需要在response中设置Access-Control-Expose-Headers
        response['Access-Control-Expose-Headers'] = 'Content-Disposition'
        # disable frame-option
        response['X-Frame-Options'] = ''
        return response

        pass

    @classmethod
    def upload_file(cls, data, user):
        # 获取文件名
        # 增加files判断是为兼容post请求files文件流参数
        files = data.get('files')
        file = files if files else data.get('file')
        path = data.get('path')
        file_name = file.name
        file_name = file_name.replace(' ', '')
        file_type = file_name.split('.')[-1]

        # 获取毫秒级时间戳作为 存入目录下的文件名
        save_name = str(int(time.time() * 1000000)) + '.' + file_type

        file_path = os.path.join(settings.MEDIA_PATH, path)

        if not os.path.exists(file_path):
            os.makedirs(file_path, 0o755)
        absolute_path = os.path.join(file_path, save_name)
        try:
            cls.write_file(absolute_path, file)
        except Exception as e:
            raise APIException(f'文件上传失败, 错误信息: {e}')

        # 将文件信息存入数据库
        ret = FileManage.objects.create(
            file_name=file_name,
            save_name=save_name,
            file_path=absolute_path,
            file_desc=data.get('file_desc'),
            file_tag=data.get('file_tag'),
            upload_user=user.username
        )

        # 返回文件路径
        return ret

    @staticmethod
    def write_file(path, file):
        with open(path, 'wb') as f:
            for chunk in file.chunks():
                f.write(chunk)
        return True
